import { groupStore, todoStore } from '../lib/data-store'
import { Group, CreateGroupRequest, UpdateGroupRequest } from '@data/group'
import { v4 as uuidv4 } from 'uuid'

export class GroupService {
  // 生成新的sortOrder
  private async generateSortOrder(parentId?: string): Promise<number> {
    const groups = await groupStore.findAll()
    const siblingGroups = groups.filter((group) => !group.deleted && group.parentId === parentId)
    return siblingGroups.length > 0 ? Math.max(...siblingGroups.map((g) => g.sortOrder)) + 1 : 1
  }

  // 获取Group列表
  async getGroups(includeDeleted: boolean = false): Promise<Group[]> {
    const groups = await groupStore.findAll()

    return groups.filter((group) => includeDeleted || !group.deleted).sort((a, b) => a.sortOrder - b.sortOrder)
  }

  // 根据ID获取Group
  async getGroupById(id: string): Promise<Group | null> {
    const group = await groupStore.findById(id)
    return group && !group.deleted ? group : null
  }

  // 创建Group
  async createGroup(data: CreateGroupRequest): Promise<Group> {
    const now = new Date().toISOString()
    const sortOrder = await this.generateSortOrder(data.parentId)

    // 验证父分组存在
    if (data.parentId) {
      const parent = await this.getGroupById(data.parentId)
      if (!parent) {
        throw new Error('Parent group not found')
      }
    }

    const group: Group = {
      id: uuidv4(),
      name: data.name,
      color: data.color,
      parentId: data.parentId,
      sortOrder,
      collapsed: false,
      createdAt: now,
      updatedAt: now,
      deleted: false,
    }

    return await groupStore.create(group)
  }

  // 更新Group
  async updateGroup(id: string, data: UpdateGroupRequest): Promise<Group | null> {
    const existing = await groupStore.findById(id)
    if (!existing || existing.deleted) {
      return null
    }

    // 验证父分组存在且不会造成循环引用
    if (data.parentId !== undefined) {
      if (data.parentId === id) {
        throw new Error('Group cannot be its own parent')
      }

      if (data.parentId) {
        const parent = await this.getGroupById(data.parentId)
        if (!parent) {
          throw new Error('Parent group not found')
        }

        // 检查循环引用
        if (await this.wouldCreateCycle(id, data.parentId)) {
          throw new Error('This would create a circular reference')
        }
      }
    }

    const updates: Partial<Group> = {
      ...data,
      updatedAt: new Date().toISOString(),
    }

    return await groupStore.update(id, updates)
  }

  // 软删除Group (及其子分组和代办)
  async deleteGroup(id: string): Promise<boolean> {
    const existing = await groupStore.findById(id)
    if (!existing || existing.deleted) {
      return false
    }

    const now = new Date().toISOString()

    // 获取所有子分组
    const childGroups = await this.getChildGroups(id, true)

    // 软删除当前分组
    await groupStore.update(id, {
      deleted: true,
      deletedAt: now,
      updatedAt: now,
    })

    // 软删除所有子分组
    for (const child of childGroups) {
      await groupStore.update(child.id, {
        deleted: true,
        deletedAt: now,
        updatedAt: now,
      })
    }

    // 软删除分组下的所有代办
    const todos = await todoStore.findAll()
    const groupIds = [id, ...childGroups.map((g) => g.id)]

    for (const todo of todos) {
      if (!todo.deleted && todo.groupId && groupIds.includes(todo.groupId)) {
        await todoStore.update(todo.id, {
          deleted: true,
          deletedAt: now,
          updatedAt: now,
        })
      }
    }

    return true
  }

  // 恢复Group
  async restoreGroup(id: string): Promise<Group | null> {
    const existing = await groupStore.findById(id)
    if (!existing || !existing.deleted) {
      return null
    }

    return await groupStore.update(id, {
      deleted: false,
      deletedAt: undefined,
      updatedAt: new Date().toISOString(),
    })
  }

  // 更新排序
  async updateSortOrder(items: { id: string; sortOrder: number }[]): Promise<void> {
    const updates = items.map((item) => ({
      id: item.id,
      data: {
        sortOrder: item.sortOrder,
        updatedAt: new Date().toISOString(),
      },
    }))

    await groupStore.bulkUpdate(updates)
  }

  // 获取子分组
  async getChildGroups(parentId: string, recursive: boolean = false): Promise<Group[]> {
    const allGroups = await this.getGroups()
    const directChildren = allGroups.filter((group) => group.parentId === parentId)

    if (!recursive) {
      return directChildren
    }

    // 递归获取所有子分组
    const allChildren: Group[] = [...directChildren]
    for (const child of directChildren) {
      const grandChildren = await this.getChildGroups(child.id, true)
      allChildren.push(...grandChildren)
    }

    return allChildren
  }

  // 检查是否会造成循环引用
  private async wouldCreateCycle(groupId: string, newParentId: string): Promise<boolean> {
    let currentParentId: string | undefined = newParentId

    while (currentParentId) {
      if (currentParentId === groupId) {
        return true
      }

      const parent = await groupStore.findById(currentParentId)
      currentParentId = parent?.parentId
    }

    return false
  }

  // 获取分组树结构
  async getGroupTree(): Promise<Group[]> {
    const allGroups = await this.getGroups()

    // 构建树结构 (只返回根分组，子分组通过递归查询获取)
    return allGroups.filter((group) => !group.parentId)
  }

  // 移动分组到新的父分组下
  async moveGroup(groupId: string, newParentId?: string): Promise<Group | null> {
    const group = await this.getGroupById(groupId)
    if (!group) {
      return null
    }

    // 验证新的父分组
    if (newParentId) {
      const newParent = await this.getGroupById(newParentId)
      if (!newParent) {
        throw new Error('New parent group not found')
      }

      if (await this.wouldCreateCycle(groupId, newParentId)) {
        throw new Error('This would create a circular reference')
      }
    }

    // 计算新的排序位置
    const newSortOrder = await this.generateSortOrder(newParentId)

    return await this.updateGroup(groupId, {
      parentId: newParentId,
      sortOrder: newSortOrder,
    })
  }
}

export const groupService = new GroupService()
